home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / lpDaemon SRC / lpd Sources / textps.c < prev   
Encoding:
C/C++ Source or Header  |  1993-03-22  |  13.9 KB  |  766 lines  |  [TEXT/KAHL]

  1. /* textps.c */
  2. /************************************************************************
  3.  * This code is from the lprps package by James Clark                    *
  4.  ************************************************************************/
  5.  
  6. #ifdef TEXTPS
  7.  
  8. #include "LPD.H"
  9. #include "lpdProtos.H"
  10.  
  11. #define A4
  12.  
  13. typedef struct output_char {
  14.     struct output_char *next;
  15.     char c;
  16.     char is_bold;
  17.     int pos;
  18. } output_char;
  19.  
  20. output_char *free_output_char_list = 0;
  21.  
  22. int tab_width = 8;
  23. #ifdef A4
  24. double page_length = 842.0;    /* in points */
  25. int lines_per_page = 66;
  26. #else
  27. double page_length = 792.0;    /* in points */
  28. int lines_per_page = 66;
  29. #endif
  30.  
  31.  
  32. //double baseline_offset = 8.0;    /* distance in points from top of page to */
  33. double baseline_offset = 28.0;    /* distance in points from top of page to */
  34.                 /* first baseline */
  35.  
  36. double vertical_spacing = 12.0;    /* in points */
  37.  
  38. double left_margin = 18.0;    /* in points */
  39. double char_width;
  40.  
  41. int pageno = 0;
  42.  
  43. char _fgetc(integer f);
  44.  
  45. #define EOF    0
  46.  
  47. char *font = "Courier";
  48. char *bold_font = "Courier-Bold";
  49. enum { NONE, ROMAN, BOLD } current_font;
  50.  
  51. void do_file(integer);
  52. void prologue(void);
  53. void trailer(void);
  54. char *prog;
  55.  
  56.  
  57. static integer fRef;
  58. double    cpi = 12.0;
  59. static LongInt size, done;
  60.  
  61. /************************************************************************
  62.  ************************************************************************/
  63. integer textps(StringPtr name, integer refNum)
  64. {
  65.     integer    err;
  66.     extern integer spool_dir;
  67.     char_width = 72.0/cpi;
  68.  
  69.     CVT_Banner_Up();
  70.  
  71.     Create("\p%tmp_file%", spool_dir, 'SIMN', 'TEXT');
  72.     if (err = FSOpen("\p%tmp_file%", spool_dir, &fRef))
  73.         FileError("\pOpening scratch file ", err);
  74.  
  75.     GetEOF(refNum, &size);
  76.     done = 0;
  77.  
  78.     prologue();
  79.     do_file(refNum);
  80.     if (!stopped) trailer();
  81.     else SetEOF(fRef, 0);
  82.  
  83.     FSClose(refNum);
  84.     FSClose(fRef);
  85.  
  86.     FSDelete(name, spool_dir);    // delete the old one
  87.     Rename("\p%tmp_file%", spool_dir, name);    // rename the new one
  88.  
  89.     if (err = FSOpen(name, spool_dir, &fRef))
  90.         FileError("\pRe-opening scratch file ", err);
  91.  
  92.     CVT_Banner_Down();
  93.  
  94.     return fRef;
  95. }
  96.  
  97.  
  98. /************************************************************************
  99.  ************************************************************************/
  100. output_char *new_output_char(void);
  101. output_char *new_output_char()
  102. {
  103.     integer    state = 0;
  104.  
  105.     WaitForState(&state);
  106.  
  107.     if (free_output_char_list)
  108.         {
  109.         output_char *tem = free_output_char_list;
  110.         free_output_char_list = free_output_char_list->next;
  111.         return tem;
  112.         }
  113.     else
  114.         {
  115.         output_char *tem;
  116.         if ((tem = (output_char *)NewPtr(sizeof(output_char))) == NULL)
  117.             {
  118.             log_printf("%s: out of memory\n", prog);
  119.             }
  120.         return tem;
  121.         }
  122. }
  123.  
  124. static Boolean last_was_cr = FALSE;
  125.  
  126. /************************************************************************
  127.  ************************************************************************/
  128. static char _fgetc(integer fRef)
  129. {
  130.     Byte    c;
  131.     LongInt    count = 1;
  132.     integer    state = 0;
  133.  
  134.     WaitForState(&state);
  135.     if (stopped) return EOF;
  136.  
  137.     if (FSRead(fRef, &count, &c))
  138.         return EOF;
  139.  
  140.     CVT_Banner_PCent( ++done, size );
  141.  
  142.     if (c == CR)
  143.         last_was_cr = TRUE;
  144.     else if (c == LF)
  145.         {
  146.         if (last_was_cr)
  147.             {
  148.             last_was_cr = FALSE;
  149.             return _fgetc(fRef);
  150.             }
  151.         else c = CR;
  152.         last_was_cr = FALSE;
  153.         }
  154.  
  155.     return (char)(c & 0x7F);
  156. }
  157.  
  158.  
  159. /************************************************************************
  160.  ************************************************************************/
  161. void delete_output_char(output_char *p);
  162. void delete_output_char(output_char *p)
  163. {
  164.     p->next = free_output_char_list;
  165.     free_output_char_list = p;
  166. }
  167.  
  168. #define isascii(c)    (!((c) & ~0177))
  169. #define iscntrl(c)    ( (c) > 0 && (c) < ' ' )
  170.  
  171. /************************************************************************
  172.  ************************************************************************/
  173. void pschar(int c);
  174. void pschar(int c)
  175. {
  176.     if (!isascii(c) || iscntrl(c))
  177.         fprintf(fRef, "\\%03o", c & 0377);
  178.     else if (c == '(' || c == ')' || c == '\\')
  179.         {
  180.         fputc(fRef, '\\');
  181.         fputc(fRef, c);
  182.         }
  183.     else
  184.         fputc(fRef, c);
  185. }
  186.  
  187. /************************************************************************
  188.  ************************************************************************/
  189. void psnum(double f);
  190. void psnum(double f)
  191. {
  192.     LongInt    l = f;
  193.     
  194.     fprintf(fRef, "%ld", l);
  195. }
  196.  
  197. /* output_line is ordered greatest position first */
  198.  
  199. /************************************************************************
  200.  ************************************************************************/
  201. void print_line(output_char *output_line, int vpos);
  202. void print_line(output_char *output_line, int vpos)
  203. {
  204.     output_char *rev = output_line;
  205.     output_line = 0;
  206.     while (rev != 0)
  207.         {
  208.         output_char *tem = rev;
  209.         rev = rev->next;
  210.         tem->next = output_line;
  211.         output_line = tem;
  212.         }
  213.     while (output_line != NULL)
  214.         {
  215.         output_char *tem;
  216.         output_char **p = &output_line;
  217.         int start_pos = output_line->pos;
  218.         int is_bold = output_line->is_bold;
  219.         int pos;
  220.         if (is_bold)
  221.             {
  222.             if (current_font != BOLD)
  223.                 {
  224.                 fprintf(fRef, "B");
  225.                 current_font = BOLD;
  226.                 }
  227.             }
  228.         else
  229.             {
  230.             if (current_font != ROMAN)
  231.                 {
  232.                 fprintf(fRef, "R");
  233.                 current_font = ROMAN;
  234.                 }
  235.             }
  236.         fputc(fRef, '(');
  237.         pschar(output_line->c);
  238.         pos = output_line->pos + 1;
  239.         tem = output_line;
  240.         output_line = output_line->next;
  241.         delete_output_char(tem);
  242.         for (;;)
  243.             {
  244.             while (*p != NULL
  245.                     && ((*p)->pos < pos || (*p)->is_bold != is_bold))
  246.                                         p = &(*p)->next;
  247.                 if (*p == NULL)
  248.                     break;
  249.             while (pos < (*p)->pos)
  250.                 {
  251.                 pschar(' ');
  252.                 pos++;
  253.                 }
  254.             pschar((*p)->c);
  255.             pos++;
  256.             tem = *p;
  257.             *p = tem->next;
  258.             delete_output_char(tem);
  259.             }
  260.         fputc(fRef, ')');
  261.         psnum(left_margin + start_pos*char_width);
  262.         fputc(fRef, ' ');
  263.         psnum(page_length - baseline_offset - vpos*vertical_spacing);
  264.         fprintf(fRef, " L\n");
  265.         }
  266. }
  267.  
  268. /************************************************************************
  269.  ************************************************************************/
  270. void page_start(void);
  271. void page_start()
  272. {
  273.     fprintf(fRef, "%%%%Page: ? %d\n%%%%BeginPageSetup\nPS\n%%%%EndPageSetup\n",
  274.                                             ++pageno);
  275.     current_font = NONE;
  276. }
  277.  
  278. /************************************************************************
  279.  ************************************************************************/
  280. void page_end(void);
  281. void page_end()
  282. {
  283.     fprintf(fRef, "PE\n");
  284. }
  285.  
  286.  
  287. /************************************************************************
  288.  ************************************************************************/
  289. char *latin1[] = {
  290.     ".notdef",
  291.     ".notdef",
  292.     ".notdef",
  293.     ".notdef",
  294.     ".notdef",
  295.     ".notdef",
  296.     ".notdef",
  297.     ".notdef",
  298.     ".notdef",
  299.     ".notdef",
  300.     ".notdef",
  301.     ".notdef",
  302.     ".notdef",
  303.     ".notdef",
  304.     ".notdef",
  305.     ".notdef",
  306.     ".notdef",
  307.     ".notdef",
  308.     ".notdef",
  309.     ".notdef",
  310.     ".notdef",
  311.     ".notdef",
  312.     ".notdef",
  313.     ".notdef",
  314.     ".notdef",
  315.     ".notdef",
  316.     ".notdef",
  317.     ".notdef",
  318.     ".notdef",
  319.     ".notdef",
  320.     ".notdef",
  321.     ".notdef",
  322.     "space",
  323.     "exclam",
  324.     "quotedbl",
  325.     "numbersign",
  326.     "dollar",
  327.     "percent",
  328.     "ampersand",
  329.     "quoteright",
  330.     "parenleft",
  331.     "parenright",
  332.     "asterisk",
  333.     "plus",
  334.     "comma",
  335.     "hyphen",
  336.     "period",
  337.     "slash",
  338.     "zero",
  339.     "one",
  340.     "two",
  341.     "three",
  342.     "four",
  343.     "five",
  344.     "six",
  345.     "seven",
  346.     "eight",
  347.     "nine",
  348.     "colon",
  349.     "semicolon",
  350.     "less",
  351.     "equal",
  352.     "greater",
  353.     "question",
  354.     "at",
  355.     "A",
  356.     "B",
  357.     "C",
  358.     "D",
  359.     "E",
  360.     "F",
  361.     "G",
  362.     "H",
  363.     "I",
  364.     "J",
  365.     "K",
  366.     "L",
  367.     "M",
  368.     "N",
  369.     "O",
  370.     "P",
  371.     "Q",
  372.     "R",
  373.     "S",
  374.     "T",
  375.     "U",
  376.     "V",
  377.     "W",
  378.     "X",
  379.     "Y",
  380.     "Z",
  381.     "bracketleft",
  382.     "backslash",
  383.     "bracketright",
  384.     "asciicircum",
  385.     "underscore",
  386.     "quoteleft",
  387.     "a",
  388.     "b",
  389.     "c",
  390.     "d",
  391.     "e",
  392.     "f",
  393.     "g",
  394.     "h",
  395.     "i",
  396.     "j",
  397.     "k",
  398.     "l",
  399.     "m",
  400.     "n",
  401.     "o",
  402.     "p",
  403.     "q",
  404.     "r",
  405.     "s",
  406.     "t",
  407.     "u",
  408.     "v",
  409.     "w",
  410.     "x",
  411.     "y",
  412.     "z",
  413.     "braceleft",
  414.     "bar",
  415.     "braceright",
  416.     "asciitilde",
  417.     ".notdef",
  418.     ".notdef",
  419.     ".notdef",
  420.     ".notdef",
  421.     ".notdef",
  422.     ".notdef",
  423.     ".notdef",
  424.     ".notdef",
  425.     ".notdef",
  426.     ".notdef",
  427.     ".notdef",
  428.     ".notdef",
  429.     ".notdef",
  430.     ".notdef",
  431.     ".notdef",
  432.     ".notdef",
  433.     ".notdef",
  434.     "dotlessi",
  435.     "grave",
  436.     "acute",
  437.     "circumflex",
  438.     "tilde",
  439.     "macron",
  440.     "breve",
  441.     "dotaccent",
  442.     "dieresis",
  443.     ".notdef",
  444.     "ring",
  445.     "cedilla",
  446.     ".notdef",
  447.     "hungarumlaut",
  448.     "ogonek",
  449.     "caron",
  450.     ".notdef",
  451.     "exclamdown",
  452.     "cent",
  453.     "sterling",
  454.     "currency",
  455.     "yen",
  456.     "brokenbar",
  457.     "section",
  458.     "dieresis",
  459.     "copyright",
  460.     "ordfeminine",
  461.     "guilsinglleft",
  462.     "logicalnot",
  463.     "registered",
  464.     "minus",
  465.     "macron",
  466.     "degree",
  467.     "plusminus",
  468.     "twosuperior",
  469.     "threesuperior",
  470.     "acute",
  471.     "mu",
  472.     "paragraph",
  473.     "periodcentered",
  474.     "cedilla",
  475.     "onesuperior",
  476.     "ordmasculine",
  477.     "guilsinglright",
  478.     "onequarter",
  479.     "onehalf",
  480.     "threequarters",
  481.     "questiondown",
  482.     "Agrave",
  483.     "Aacute",
  484.     "Acircumflex",
  485.     "Atilde",
  486.     "Adieresis",
  487.     "Aring",
  488.     "AE",
  489.     "Ccedilla",
  490.     "Egrave",
  491.     "Eacute",
  492.     "Ecircumflex",
  493.     "Edieresis",
  494.     "Igrave",
  495.     "Iacute",
  496.     "Icircumflex",
  497.     "Idieresis",
  498.     "Eth",
  499.     "Ntilde",
  500.     "Ograve",
  501.     "Oacute",
  502.     "Ocircumflex",
  503.     "Otilde",
  504.     "Odieresis",
  505.     "multiply",
  506.     "Oslash",
  507.     "Ugrave",
  508.     "Uacute",
  509.     "Ucircumflex",
  510.     "Udieresis",
  511.     "Yacute",
  512.     "Thorn",
  513.     "germandbls",
  514.     "agrave",
  515.     "aacute",
  516.     "acircumflex",
  517.     "atilde",
  518.     "adieresis",
  519.     "aring",
  520.     "ae",
  521.     "ccedilla",
  522.     "egrave",
  523.     "eacute",
  524.     "ecircumflex",
  525.     "edieresis",
  526.     "igrave",
  527.     "iacute",
  528.     "icircumflex",
  529.     "idieresis",
  530.     "eth",
  531.     "ntilde",
  532.     "ograve",
  533.     "oacute",
  534.     "ocircumflex",
  535.     "otilde",
  536.     "odieresis",
  537.     "divide",
  538.     "oslash",
  539.     "ugrave",
  540.     "uacute",
  541.     "ucircumflex",
  542.     "udieresis",
  543.     "yacute",
  544.     "thorn",
  545.     "ydieresis",
  546. };
  547.     
  548. /************************************************************************
  549.  ************************************************************************/
  550. void prologue()
  551. {
  552.     integer col, i, len;
  553.     char    *ls;
  554.  
  555.     fprintf(fRef, "%%!PS-Adobe-3.0\n");
  556.     fprintf(fRef, "%%%%DocumentNeededResources: font %s\n", font);
  557.     fprintf(fRef, "%%%%+ font %s\n", bold_font);
  558.     fprintf(fRef, "%%%%Pages: (atend)\n");
  559.     fprintf(fRef, "%%%%EndComments\n");
  560.     fprintf(fRef, "%%%%BeginProlog\n");
  561.     fprintf(fRef, "/textps 10 dict def textps begin\n");
  562.  
  563.     fprintf(fRef, "/L { moveto show } bind def\n");
  564.     fprintf(fRef, "/PS { /level0 save def } bind def\n");
  565.     fprintf(fRef, "/PE { level0 restore showpage } bind def\n");
  566.     fprintf(fRef, "/RE {\n");
  567.     fprintf(fRef, "\tfindfont\n");
  568.     fprintf(fRef, "\tdup maxlength dict begin\n");
  569.     fprintf(fRef, "\t{\n");
  570.     fprintf(fRef, "\t\t1 index /FID ne { def } { pop pop } ifelse\n");
  571.     fprintf(fRef, "\t} forall\n");
  572.     fprintf(fRef, "\t/Encoding exch def\n");
  573.     fprintf(fRef, "\tdup /FontName exch def\n");
  574.     fprintf(fRef, "\tcurrentdict end definefont pop\n");
  575.     fprintf(fRef, "} bind def\n");
  576.  
  577.     fprintf(fRef, "/ISOLatin1Encoding where{pop}{/ISOLatin1Encoding[\n");
  578.  
  579.     col = 0;
  580.     for (i = 0; i < 256; i++)
  581.         {
  582.         ls = latin1[i];
  583.         len = strlen(ls) + 1;
  584.         col += len;
  585.         if (col > 79)
  586.             {
  587.     //        fputc(fRef, '\n');
  588.             fputc(fRef, CR);
  589.             col = len;
  590.             }
  591.         fprintf(fRef, "/%s", ls);
  592.         }
  593.  
  594.     fprintf(fRef, "\n] def}ifelse\nend\n");
  595.     fprintf(fRef, "%%%%BeginSetup\n");
  596.     fprintf(fRef, "%%%%IncludeResource: font %s\n", font);
  597.     fprintf(fRef, "%%%%IncludeResource: font %s\n", bold_font);
  598.     fprintf(fRef, "textps begin\n");
  599.     fprintf(fRef, "/__%s ISOLatin1Encoding /%s RE\n", font, font);
  600.     fprintf(fRef, "/R [ /__%s findfont ", font);
  601.         psnum(char_width/.6);
  602.     fprintf(fRef, " scalefont /setfont load ] cvx def\n");
  603.     fprintf(fRef, "/__%s ISOLatin1Encoding /%s RE\n", bold_font, bold_font);
  604.     fprintf(fRef, "/B [ /__%s findfont ", bold_font);
  605.         psnum(char_width/.6);
  606.     fprintf(fRef, " scalefont /setfont load ] cvx def\n");
  607.     fprintf(fRef, "%%%%EndSetup\n");
  608.     fprintf(fRef, "%%%%EndProlog\n");
  609. }
  610.  
  611. /************************************************************************
  612.  ************************************************************************/
  613. void trailer()
  614. {
  615.     fprintf(fRef, "%%%%Trailer\nend\n%%%%Pages: %d\n", pageno);
  616. }
  617.  
  618. /* p is ordered greatest position first */
  619.  
  620. /************************************************************************
  621.  ************************************************************************/
  622. void add_char(int c, int pos, output_char **p);
  623. void add_char(int c, int pos, output_char **p)
  624. {
  625.     for (;; p = &(*p)->next)
  626.         {
  627.         if (*p == NULL || (*p)->pos < pos)
  628.             {
  629.             output_char *tem = new_output_char();
  630.             tem->next = *p;
  631.             *p = tem;
  632.             tem->c = c;
  633.             tem->is_bold = 0;
  634.             tem->pos = pos;
  635.             break;
  636.             }
  637.         else if ((*p)->pos == pos)
  638.             {
  639.             if (c == (*p)->c)
  640.                 {
  641.                 (*p)->is_bold = 1;
  642.                 break;
  643.                 }
  644.             }
  645.         }
  646. }
  647.  
  648. /************************************************************************
  649.  ************************************************************************/
  650. void do_file(integer fp)
  651. {
  652.     int c;
  653.     int vpos = 0;
  654.     int hpos = 0;
  655.     int page_started = 0;
  656.     int esced = 0;
  657.  
  658.     output_char *output_line = 0;
  659.     while ((c = _fgetc(fp)) != EOF)
  660.         {
  661.         MainEvents(everyEvent);
  662.         if (esced)
  663.             {
  664.             switch(c)
  665.                 {
  666.                 case '7':
  667.                     if (vpos > 0)
  668.                         {
  669.                         if (output_line != NULL)
  670.                             {
  671.                             if (!page_started)
  672.                                 {
  673.                                 page_started = 1;
  674.                                 page_start();
  675.                                 }
  676.                             print_line(output_line, vpos);
  677.                             output_line = 0;
  678.                             }
  679.                         vpos -= 1;
  680.                         }
  681.                     /* hpos = 0; */
  682.                     esced = 0;
  683.                     break;
  684.                 default:
  685.                     /* silently ignore */
  686.                     esced = 0;
  687.                     break;
  688.                 }
  689.             }
  690.         else
  691.             {
  692.             switch (c)
  693.                 {
  694.                 case '\033':
  695.                     esced = 1;
  696.                     break;
  697.                 case '\b':
  698.                     if (hpos > 0)
  699.                         hpos--;
  700.                     break;
  701.                 case '\f':
  702.                     if (!page_started)
  703.                         page_start();
  704.                     print_line(output_line, vpos);
  705.                     output_line = 0;
  706.                     page_end();
  707.                     hpos = 0;        /* ?? */
  708.                     vpos = 0;
  709.                     page_started = 0;
  710.                     break;
  711.                 case CR:
  712.                     hpos = 0;
  713.                     break;
  714.                 case LF:
  715.                     if (output_line != NULL)
  716.                         {
  717.                         if (!page_started)
  718.                             {
  719.                             page_started = 1;
  720.                             page_start();
  721.                             }
  722.                         print_line(output_line, vpos);
  723.                         output_line = 0;
  724.                         }
  725.                     vpos += 1;
  726.                     if (vpos >= lines_per_page)
  727.                         {
  728.                         if (!page_started)
  729.                             page_start();
  730.                         page_end();
  731.                         page_started = 0;
  732.                         vpos = 0;
  733.                         }
  734.                     hpos = 0;
  735.                     break;
  736.                 case ' ':
  737.                     hpos++;
  738.                     break;
  739.                 case '\t':
  740.                     hpos = ((hpos + tab_width)/tab_width)*tab_width;
  741.                     break;
  742.                 default:
  743.                     if (!(isascii(c) && iscntrl(c)))
  744.                         {
  745.                         add_char(c, hpos, &output_line);
  746.                         hpos++;
  747.                         }
  748.                     break;
  749.                 }
  750.             }
  751.         }
  752.     if (output_line != NULL)
  753.         {
  754.         if (!page_started)
  755.             {
  756.             page_started = 1;
  757.             page_start();
  758.             }
  759.         print_line(output_line, vpos);
  760.         output_line = 0;
  761.         }
  762.     if (page_started)
  763.         page_end();
  764. }
  765. #endif
  766.